package com.bs.service.impl;

import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.StrUtil;
import com.bs.model.User;
import com.bs.service.IAuthService;
import com.bs.service.IUserService;
import com.bs.vo.LoginVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

/**
 * 说明：
 *
 * @author 琪
 * @since 2025/5/7 21:51
 */
@Service
@Slf4j
public class AuthServiceImpl implements IAuthService {

    @Autowired
    private IUserService userService;

    /**
     * 用户登录过期时间
     * key: token
     * value: LoginVo
     */
    Map<String, LoginVo> tokenLoginCache = new ConcurrentHashMap<>();

    /**
     * 登录过期时间（小时）默认24小时
     */
    private long expireTimeHours = 24;

    @Override
    public LoginVo login(String name, String password) {
        User user = userService.getUser(name);
        if (user != null && user.getPassword().equals(password)) {
            // 登录验证成功，记录登录状态。
            long now = System.currentTimeMillis();
            long expire = now + TimeUnit.HOURS.toMillis(expireTimeHours);
            String token = UUID.randomUUID().toString();

            LoginVo loginVo = new LoginVo();
            loginVo.setToken(token);
            loginVo.setExpire(expire);
            loginVo.setUser(user);
            tokenLoginCache.put(token, loginVo);
            log.info("用户登录成功：{}", loginVo);
            return loginVo;
        }
        throw new RuntimeException("用户名或密码错误");
    }

    @Override
    public void logout() {
        String token = getToken();
        if (token == null || token.isEmpty()) {
            throw new RuntimeException("登录过期");
        }
        LoginVo loginVo = tokenLoginCache.get(token);
        if (loginVo == null) {
            throw new RuntimeException("登录过期");
        }
        log.info("用户退出登录：{}", loginVo);
        tokenLoginCache.remove(token);
    }

    @Override
    public User register(User user) {
        // 检查用户名不能为空
        if (user.getName() == null || user.getName().isEmpty()) {
            throw new RuntimeException("用户名不能为空");
        }
        // 检查密码不能为空
        if (user.getPassword() == null || user.getPassword().isEmpty()) {
            throw new RuntimeException("密码不能为空");
        }
        User existUser = userService.getUser(user.getName());
        if (existUser != null) {
            throw new RuntimeException("用户名已存在");
        }
        userService.save(user);
        return user;
    }


    public static HttpServletRequest getCurrentHttpRequest() {
        try {
            return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        } catch (Exception e) {
            // Handle exception as needed
            return null;
        }
    }

    public String getToken() {
        HttpServletRequest request = getCurrentHttpRequest();
        if (request == null) {
            return null;
        }
        return request.getHeader("Authorization");
    }

    @Override
    public LoginVo getLoginUser() {
        String token = getToken();

        if (token == null || token.isEmpty()) {
            throw new RuntimeException("登录过期");
        }
        /*
        验证用户登录， 如果过期时间小于当前时间，登录过期.
         */
        long now = System.currentTimeMillis();
        LoginVo loginVo = tokenLoginCache.get(token);
        if (loginVo == null) {
            throw new RuntimeException("登录过期");
        }
        Long expire = loginVo.getExpire();
        if (expire == null || now > expire) {
            throw new RuntimeException("登录过期");
        }
        return loginVo;
    }

    @Override
    public void changePass(String oldPass, String newPass) {
        LoginVo loginUser = getLoginUser();
        if (StrUtil.isBlank(oldPass)) {
            throw new RuntimeException("旧密码不能为空");
        }
        if (StrUtil.isBlank(newPass)) {
            throw new RuntimeException("新密码不能为空");
        }
        if (oldPass.equals(newPass)) {
            throw new RuntimeException("密码相同, 禁止修改");
        }
        String id = loginUser.getUser().getId();
        String name = loginUser.getUser().getName();
        log.info("用户 {} 请求修改新密码", name);
        User oldUser = userService.getById(id);
        String dbPass = oldUser.getPassword();
        if (!oldPass.equals(dbPass)) {
            throw new RuntimeException("密码错误");
        }
        User update = new User();
        update.setId(loginUser.getUser().getId());
        update.setPassword(newPass);
        boolean updateById = userService.updateById(update);
        log.info("用户 {} 请求修改新密码结果: {}", name, updateById);
    }

}
